from flask import Response, jsonify, Flask, request, Blueprint,url_for
from configs import *
from modules.Tables import *
from sqlalchemy import func



# 创建蓝图，对应的register目录（激活操作视图）
video_view = Blueprint('video', __name__)


def get_rtsp_url(em_data, par_id_ip=None, is_history=False, start_time=None, end_time=None):
    """
    生成 RTSP URL
    :param em_data: 摄像头设备数据
    :param par_id_ip: 父设备 IP 数据
    :param is_history: 是否为历史回放
    :param start_time: 回放起始时间（仅录像机）
    :param end_time: 回放结束时间（仅录像机）
    :return: 生成的 RTSP URL
    """
    if is_history:
        # 历史回放
        if par_id_ip:
            return "rtsp://{}:{}@{}:554/Streaming/tracks/{}starttime={}z&endtime={}z".format(
                urllib.parse.quote(em_data.equipment_uname),
                urllib.parse.quote(em_data.equipment_password),
                urllib.parse.quote(par_id_ip.equipment_ip),
                urllib.parse.quote(em_data.code),
                start_time,
                end_time,
            )
        else:
            return ""
    else:
        # 实时视频
        if par_id_ip:
            return "rtsp://{}:{}@{}:554/Streaming/Unicast/Channels/{}".format(
                urllib.parse.quote(em_data.equipment_uname),
                urllib.parse.quote(em_data.equipment_password),
                urllib.parse.quote(par_id_ip.equipment_ip),
                urllib.parse.quote(em_data.code),
            )
        else:
            return "rtsp://{}:{}@{}".format(
                urllib.parse.quote(em_data.equipment_uname),
                urllib.parse.quote(em_data.equipment_password),
                urllib.parse.quote(em_data.equipment_ip),
            )

# 实时视频推流接口（视频分析）
@video_view.route('/real_time_video', methods=['GET'])
@jwt_required()
def real_time_video():
    """
    实时视频推流接口

    参数:
        model_path (str): 模型id
        linux_ip (str): RTMP 服务器 IP 地址。
        rtsp_url (str): RTSP 流媒体源地址。
        width (str): 视频宽度。
        height (str): 视频高度。
        frame_r (str): 比特率。
        baud_b (str): 帧率。
        stream_data_flag (str): 运行标识   1运行  0 删除。
        video_type (str): 运行标识   1 实时视频  2录像回放
        start_time (str): 开始时间
        end_time (str):   结束时间
    """
    rtmp_server_ip=DB_HOST
    em_id = strip_whitespace(request.args.get('em_id',None) ) # 摄像头id
    width = strip_whitespace(request.args.get('width',1920))  # 视频宽度
    height = strip_whitespace(request.args.get('height',1080))  # 视频高度
    frame_r = strip_whitespace(request.args.get('frame_r',1000))  # 比特率
    baud_b = strip_whitespace(request.args.get('baud_b',25))  # 帧率
    stream_data_flag = strip_whitespace(request.args.get('stream_data_flag',None))  # 运行标识  1运行  3 删除
    video_status = strip_whitespace(request.args.get('video_status','1'))  # 运行标识   1 实时视频  2录像回放
    start_time = strip_whitespace(request.args.get('start_time',None))  # 运行标识   开始时间
    end_time = strip_whitespace(request.args.get('end_time',None))  # 运行标识   结束时间
    model_id = strip_whitespace(request.args.get('model_id',None))  # 模型id


    # 参数构建判断是否为空
    params = [rtmp_server_ip, em_id, width, height, frame_r, baud_b, stream_data_flag,model_id]

    if not all(params):
        return jsonify({'code': 400, 'msg': '设备数据有未填写项'})

    r3 = redis.Redis(host=Redis_ip, port=Redis_port, password=Redis_password, decode_responses=True, db=3)

    print(em_id,'11')
    # 获取模型路径
    model_path = db.session.query(Algorithm_library).filter(Algorithm_library.id==model_id).first()
    if not model_path:
        return jsonify({'code': 400, 'msg': '该模型不存在!'})

    # 获取摄像头信息
    em_data = db.session.query(Equipment).filter(Equipment.id == em_id).first()
    if not em_data and em_data.online != '1':
        return jsonify({'code': 400, 'msg': '该监控点不存在或不在线!'})

    # 获取父设备信息（若存在）
    par_id_ip = None
    if em_data.VCR_data_id and em_data.parent_id:
        par_id_ip = db.session.query(Equipment).filter(Equipment.id == em_data.parent_id).first()

    # 根据 video_status 生成对应 RTSP URL
    is_history = (video_status != '1')
    rtsp_url = get_rtsp_url(em_data, par_id_ip, is_history, start_time, end_time)

    if not rtsp_url:
        return jsonify({'code': 400, 'msg': '无法生成有效的 RTSP 流 URL!'})

    print("生成的 RTSP URL:", rtsp_url)

    def extract_ip_from_rtsp(rtsp_url):
        """从 RTSP URL 中提取 IP 地址"""
        # 使用正则表达式匹配 IP 地址
        match = re.search(r'(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', rtsp_url)

        if match:
            return match.group(1)
        else:
            return None

    try:
        # 提取ip
        ip_address = extract_ip_from_rtsp(rtsp_url)
        print("提取的 IP 地址:", ip_address)

        pinger = Pinger(target_host=ip_address)
        delay = pinger.ping_once()
        if delay == None:
            return jsonify({'code': 400, 'msg': '当前监控点不在线!'})
    except Exception as e:
            return jsonify({'code': 400, 'msg': '当前监控点不在线!'})

    # 定义一个字典来保存要设置的键值对
    data_to_set = {
        "rtsp_url": rtsp_url,
        "rtmp_server_ip": rtmp_server_ip,
        "width": width,
        "height": height,
        "frame_r": frame_r,
        "baud_b": baud_b,
        "stream_data_flag": stream_data_flag,
        "model_path": model_path.algorithm_path,
    }

    # 使用 r3 直接设置每个键值对
    for key, value in data_to_set.items():
        print(f"设置 {key} = {value} 到 r3")  # 打印设置内容
        r3.set(key, value)

    return jsonify({'code': 200,'msg':'推流成功','flv_url':'http://{}:8080/live/stream.flv'.format(rtmp_server_ip)})

# 实时视频状态检测（视频分析）
@video_view.route('/real_time_video_status', methods=['GET'])
@jwt_required()
def real_time_video_status():
    r3 = redis.Redis(host=Redis_ip, port=Redis_port, password=Redis_password, decode_responses=True, db=3)
    video_type = r3.get('video_type')
    if video_type == '1':
        video_type = 'http://{}:8080/live/stream.flv'.format(DB_HOST)
        return jsonify({'code': 200, 'video_type': video_type})
    else:
        return jsonify({'code': 201, 'video_type':'视频分析停止'})


# 实时视频停止推流（视频分析）
@video_view.route('/real_time_video_stop', methods=['GET'])
@jwt_required()
def real_time_video_stop():
    r3 = redis.Redis(host=Redis_ip, port=Redis_port, password=Redis_password, decode_responses=True, db=3)
    r3.set('stream_data_flag',3)
    return jsonify({'code': 200, 'video_type':'视频分析停止'})


# 报警视频停止推流（视频分析）
@video_view.route('/alg_video_stop', methods=['GET'])
@jwt_required()
def alg_video_stop():
    r3 = redis.Redis(host=Redis_ip, port=Redis_port, password=Redis_password, decode_responses=True, db=4)
    r3.set('stream_data_flag',3)
    return jsonify({'code': 200, 'video_type':'视频分析停止'})




# 报警配置视频推送（视频分析）
@video_view.route('/alg_conf_video', methods=['GET'])
# @jwt_required()
def alg_conf_video():
    """
    报警配置视频推送

    参数:
        rtmp_server_ip (str): RTMP 服务器 IP 地址。
        config_id：算法配置id
        rtsp_url (str): RTSP 流媒体源地址。
        width (str): 视频宽度。
        height (str): 视频高度。
        frame_r (str): 比特率。
        baud_b (str): 帧率。
        stream_data_flag (str): 运行标识   1运行  0 删除。
    """

    rtmp_server_ip=DB_HOST
    config_id = strip_whitespace(request.args.get('config_id',None))  # 视频宽度
    width = strip_whitespace(request.args.get('width',1080))  # 视频宽度
    height = strip_whitespace(request.args.get('height',1920))  # 视频高度
    frame_r = strip_whitespace(request.args.get('frame_r',1300))  # 比特率
    baud_b = strip_whitespace(request.args.get('baud_b',6))  # 帧率
    stream_data_flag = strip_whitespace(request.args.get('stream_data_flag',0))  # 运行标识  1运行  3 删除


    # 参数构建判断是否为空
    params = [rtmp_server_ip, config_id, width, height, frame_r, baud_b, stream_data_flag]

    if not all(params):
        return jsonify({'code': 400, 'msg': '设备数据有未填写项'})

    r3 = redis.Redis(host=Redis_ip, port=Redis_port, password=Redis_password, decode_responses=True, db=4)

    # 定义一个字典来保存要设置的键值对
    data_to_set = {
        "config_id":config_id,
        "rtmp_server_ip": rtmp_server_ip,
        "width": width,
        "height": height,
        "frame_r": frame_r,
        "baud_b": baud_b,
        "stream_data_flag": stream_data_flag,
        "video_type":3,
    }

    # 使用 r3 直接设置每个键值对
    for key, value in data_to_set.items():
        print(f"设置 {key} = {value} 到 r3")  # 打印设置内容
        r3.set(key, value)

    return jsonify({'code':200,'message':'配置监控点检测进行中'})


# 报警配置视频状态检测（视频分析）
@video_view.route('/alg_status_video', methods=['GET'])
def alg_status_video():
    r3 = redis.Redis(host=Redis_ip, port=Redis_port, password=Redis_password, decode_responses=True, db=4)
    video_type = r3.get('video_type')
    if video_type == '1':
        video_type = 'http://{}:8080/live/stream1.flv'.format(DB_HOST)
        return jsonify({'code': 200, 'video_type': video_type})
    elif video_type=='2':
        video_type='暂无对应时间报警图片'
        return jsonify({'code': 201, 'video_type': video_type})
    else:
        return jsonify({'code':203,'video_type':video_type})
